package com.yuantu.judiciary.serviceimpl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.URLUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.BankcardExtInfo;
import com.alipay.api.domain.Participant;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.alipay.easysdk.base.oauth.models.AlipaySystemOauthTokenResponse;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.member.identification.models.*;
import com.alipay.easysdk.payment.common.models.AlipayTradeCreateResponse;
import com.alipay.easysdk.util.generic.models.AlipayOpenApiGenericResponse;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.yuantu.judiciary.model.api_ali.AlipayUserInfoShareResponseDTO;
import com.yuantu.judiciary.model.dto.AddOrderDTO;
import com.yuantu.judiciary.service.IApiAliAppletService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;


import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 支付宝小程序
 *
 * @author syw
 * @since 2023-12-20
 **/
@Service
@RequiredArgsConstructor
@Slf4j
public class ApiAliAppletServiceImpl implements IApiAliAppletService {

    private static final Gson GSON = new Gson();
    public static Config open_config;
    public static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi/7rUBi4mm2rHzSW0BLey52A69zvbXiE7gz0bvqSKKJSSpLdvBZxhseQBSuUoaOSNzmna5ov1uu0pYC1vWGHsf7YjzcrAl8aYBL+wpVAsjij+fLTeftYleVZZPjIZfGtrggDuO3L4vVrmyszOqRFS9063jy4xnfYsBwXJjmaw2vmXx6BFE+WKAmytgcopk44Jt9HZqezRtV0HcuMnBYfXW1s/9/blqNpphzpk8tWBeb9/kE0gZ2+SkLqU2Gpnn/ImeOWRs5yDKYAOYDec8AAABPGo6F3MRNAX2OSkhce1lnZV9VQvwiotbg5Az8IftwYWVyTXPqOfv/++kj5psyPnQIDAQAB";

    public static Config getOptions() {
        if (open_config == null) {
            Config config = new Config();
            config.protocol = "https";
            config.gatewayHost = "openapi.alipay.com";
            config.signType = "RSA2";
            config.appId = "2021004127601212";
            config.merchantPrivateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCxwm3NCgZA7N6CQSBRkJUywHw9U2hgFmD8Er/5ZZQ72tMGW7ot0svR/eFA8m4oheYfIwCvkvtyUBgZzUt9IRHkXoEDXCPF4Nefjx7AcIAxIiW6y5Z5ZqxxCr2oYWRbEVM4otI2c4Zib1WRdQO6wCmhBQKwgrraqFKYYTkBsvQu4dacJ0VOEmdPNojMMHC+5TQFp3wu3cEEcolMuPOV4748PSFddA7jYfBRi5gQtfwiaYGrprICCvg3oq2G+Gdx/AhkUMMhZASW22rHi0Ng0C/0ucCL3znBGzF+7tZBn+I+KFp6Ua6fZZ3zNVZONoT4DMyw2Tdp6gxPHPJvDbOE0GERAgMBAAECggEAYx95XQnG/PNZDKdGX1VRbVCatxPIszQndsj51heHtmzKmdQSmLTgRUPeFPpa5Svta9V372/12QPCvLiW7LrBIGh2Zqo9pH1Bn88OJd9WDI/vHB+k1COl6w9DPR65+HJLxtw8fnKjMEbHH2px3vSDAjAqFMWBbqbIEAK+6CyjL3R83BlshcWnpswQqTEV0egUdl8fyq0Gr2Q3jE55UHJT1pRqjPKwSwgTmH14bQgmqzfNyRt9mlAyOf5qzR77C3OOV9grTLTZji6ZPbOYF+OCZFhMpTrruZLKib7Mu65SBWidSG8J2rQIpIMqA6EZT0RAGh/VF3Rerl+/GdSCNG+mQQKBgQD6f7XvHFYxdqOVm3Wd1yc/cs6yfadhL8bAtP+FQVFCTQS6uJgXQe3qp7Jm+RZ/q8zsJ5vah3ecSaAwJJzfYVQfJJU0ZE9d/urrDxe1RqT3HPhPxcKXZicjC3twfiPDgQijPu1J8jSjANw6ZAJpz6wNEBUoIMPiHdDg4ubhLHiaSQKBgQC1qcgo+3OkVWuUC7lL8h4Blfsh7e0yafwP311t3JBhb1ke5UTk+mhsokhQS9sPMFOZKLclst6lTnGj+nP2yLd6UixjGRHx6WZ2EMBYlIWkNBIMP12SSgodVwku8+Acx3yncTeAuDfUK3nIsjfh2o/QH05Ga6qzG7m+VI4hz5dQiQKBgQC3DiTRu49xThV0+soUsmnIAAn0fcaXSuafZKVlp7nODaJrIQJj3JYUaMACZ/x9B/sUiE1ogJ5z44ngJKFOzD1BFObEBpnJQsRBSiI1Io7i1pTPFuGA6fGntnhaWJOiBuVdBls5MnostDA7q2HoGQ7N7PbJAEilMMy3ypiV7H2loQKBgEpJk8Cukyuwgr2Xzb5w1DRx0LCfS1BCZwFWpi429BPkJN2tg+7fN7S06D1tx7b+XDFVpQ+VhdazrWURFjrk+aLb16rupZf3ih7d2specggkAv1fLDSWcmxtGyRINm2OZjtS4Q+SRcJNxQ99UbzaU9UX+Dpz7OoxfFOI4FaTPZ2BAoGAQ2uMGmWjI07pEc+4AEPW7xV4TNympaWiWsmTQnULKCGNT+wihJIrF7gfXo/zn39b7RGxMfD46ijM0eFVxPvyxl2VStNtYYCHsWw1OOg9u/5ShQMNgHy+2Oo+fIViqdrAKrW2E5U/HjcXAdA55ex8rUCqlZmZ8grnojRgJf+FQFs=";
            config.alipayPublicKey = PUBLIC_KEY;
            //可设置异步通知接收服务地址（可选）
//            config.notifyUrl = "https://cxb.learncoder.com:8901/api/order/notify/applet/ali";

            //可设置AES密钥，调用AES加解密相关接口时需要（可选）
            config.encryptKey = "RuDbsgUBfQIueD+lHe3gvQ==";
            return config;
        } else {
            return open_config;
        }
    }

    @Override
    public AlipayUserInfoShareResponseDTO getUserInfo(String code) {
        Factory.setOptions(getOptions());
        try {
            AlipaySystemOauthTokenResponse token = Factory.Base.OAuth().getToken(code);

            Map<String, String> textParams = new HashMap<>();
            Map<String, Object> bizParams = new HashMap<>();
            AlipayOpenApiGenericResponse response = Factory.Util.Generic().auth(token.getAccessToken()).execute("alipay.user.info.share", textParams, bizParams);
            if (response != null && StringUtils.isNotBlank(response.getHttpBody())) {
                JsonObject object = GSON.fromJson(response.getHttpBody(), JsonObject.class);
                if (!object.get("alipay_user_info_share_response").isJsonNull()) {
                    AlipayUserInfoShareResponseDTO res = GSON.fromJson(object.get("alipay_user_info_share_response"), AlipayUserInfoShareResponseDTO.class);
                    if (res.getCode() != null && "10000".equals(res.getCode()) && (res.getMsg() != null && "Success".equals(res.getMsg()))) {
                        return res;
                    } else {
                        log.info("支付宝小程序-获取用户信息失败，返回值：{}", response.getHttpBody());
                    }
                } else {
                    log.info("支付宝小程序-获取用户信息失败，返回值：{}", response.getHttpBody());
                }
            }
        } catch (Exception e) {
            log.error("支付宝小程序-获取用户信息异常，原因：" + e.getMessage(), e);
        }
        return null;
    }

    @Override
    public String getUserPhoneInfo(String param, String sign) {
        Factory.setOptions(getOptions());
        try {
            // 验证签名
            String signContent = "\"" + param + "\"";
            String charset = "UTF-8";
            String signType = "RSA2";
            boolean verifyNotify = AlipaySignature.verify(signContent, sign, PUBLIC_KEY, charset, signType);
            if (!verifyNotify) {
                log.info("[支付宝小程序] 获取用户手机号签名验证失败");
                return "";
            }

            // 解密手机号
            String response = Factory.Util.AES().decrypt(param);
            if (StringUtils.isNotBlank(response)) {
                JsonObject object = GSON.fromJson(response, JsonObject.class);
                boolean verify = (object.get("code") != null && "10000".equals(object.get("code").getAsString()))
                        && (object.get("msg") != null && "Success".equals(object.get("msg").getAsString()));
                if (verify) {
                    return object.get("mobile") != null ? object.get("mobile").getAsString() : "";
                } else {
                    log.info("支付宝小程序-获取用户手机号失败，返回值：{}", response);
                }
            }
        } catch (Exception e) {
            log.error("支付宝小程序-获取用户手机号异常，原因：" + e.getMessage(), e);
        }
        return "";
    }

    /**
     * 初始化身份认证
     */
    @Override
    public String identificationInit(String username, String idNumber) {
        Factory.setOptions(getOptions());
        String outerOrderNo = IdUtil.simpleUUID();
        String bizCode = "FACE";
        IdentityParam identityParam = new IdentityParam();
        identityParam.setIdentityType("CERT_INFO");
        identityParam.setCertType("IDENTITY_CARD");
        identityParam.setCertName(username);
        identityParam.setCertNo(idNumber);
        MerchantConfig merchantConfig = new MerchantConfig();
        merchantConfig.setReturnUrl("");

        try {
            AlipayUserCertifyOpenInitializeResponse response = Factory.Member.Identification().init(outerOrderNo, bizCode, identityParam, merchantConfig);

            if (ResponseChecker.success(response)) {
                log.info("[支付宝小程序-身份验证]初始化身份认证成功:{}, 生成的 certifyId:{}", username, response.getCertifyId());
                return response.getCertifyId();
            } else {
                log.info("[支付宝小程序-身份验证]初始化身份认证失败:{}, 返回值:{}", username, GSON.toJson(response));
            }
        } catch (Exception e) {
            log.error("[支付宝小程序-身份验证]初始化身份认证失败:{}", username, e);
        }
        return null;
    }

    @Override
    public String identificationCertify(String certifyId) {
        Factory.setOptions(getOptions());
        try {
            AlipayUserCertifyOpenCertifyResponse response = Factory.Member.Identification().certify(certifyId);
            if (ResponseChecker.success(response)) {
                log.info("[支付宝小程序-身份验证] certifyId:{} 开始身份认证成功, 生成的链接:{}", certifyId, response.getBody());
                return response.getBody();
            } else {
                log.info("[支付宝小程序-身份验证] certifyId:{} 开始身份认证失败, 返回值:{}", certifyId, GSON.toJson(response));
            }
        } catch (Exception e) {
            log.error("[支付宝小程序-身份验证] certifyId:{} 开始身份认证失败", certifyId, e);
        }
        return null;
    }

    @Override
    public String identificationQuery(String certifyId) {
        Factory.setOptions(getOptions());
        try {
            AlipayUserCertifyOpenQueryResponse response = Factory.Member.Identification().query(certifyId);
            if (ResponseChecker.success(response)) {
                log.info("[支付宝小程序-身份验证] certifyId:{} 获取认证结果成功, 认证结果为:{}", certifyId, response.getHttpBody());
                return response.getHttpBody();
            } else {
                log.info("[支付宝小程序-身份验证] certifyId:{} 获取认证结果失败, 返回值:{}", certifyId, GSON.toJson(response));
            }
        } catch (Exception e) {
            log.error("[支付宝小程序-身份验证] certifyId:{} 获取认证结果失败", certifyId, e);
        }
        return null;
    }

    @Override
    public String getUserId(Long accountId, String authCode) {
        Factory.setOptions(getOptions());
        try {
            AlipaySystemOauthTokenResponse response = Factory.Base.OAuth().getToken(authCode);
            if (ResponseChecker.success(response)) {
                log.info("[支付宝小程序] 用户:{} 获取 userId 成功, 授权信息为:{}", accountId, response.getHttpBody());
                return response.getUserId();
            } else {
                log.info("[支付宝小程序] 用户:{} 获取 userId 失败, 返回值:{}", accountId, GSON.toJson(response));
            }
        } catch (Exception e) {
            log.error("[支付宝小程序] 用户:{} 获取 userId 失败", accountId, e);
        }
        return null;
    }

    @Override
    public AlipayTradeCreateResponse addOrder(Long accountId, AddOrderDTO data) {
        Config options = getOptions();
        options.notifyUrl = "https://admin.njxnet.com:8901/api/order/notify/applet/ali";
        Factory.setOptions(options);
        try {
            AlipayTradeCreateResponse response = Factory.Payment.Common().create(data.getName(), data.getTradeNo(), data.getTotalPrice().toString(), data.getOpenId());
            if (ResponseChecker.success(response)) {
                log.info("[支付宝小程序] 用户:{} 创建订单成功,订单号为:{}", accountId, response.getOutTradeNo());
                return response;
            } else {
                log.info("[支付宝小程序] 用户:{} 创建订单失败，返回值：{}", accountId, GSON.toJson(response));
            }
        } catch (Exception e) {
            log.error("[支付宝小程序] 用户:{} 创建订单异常", accountId, e);
        }
        return null;
    }


    @Override
    public AlipayTradeCreateResponse addOrderForMembershipCard(Long accountId, AddOrderDTO data) {
        Config options = getOptions();
        options.notifyUrl = "https://admin.njxnet.com:8901/api/order/notify/applet/ali/membership/card";
        Factory.setOptions(options);
        try {
            AlipayTradeCreateResponse response = Factory.Payment.Common().create(data.getName(), data.getTradeNo(),
                    data.getTotalPrice().toString(), data.getOpenId());
            if (ResponseChecker.success(response)) {
                log.info("[支付宝小程序] 用户:{} 创建订单成功,订单号为:{}", accountId, response.getOutTradeNo());
                return response;
            } else {
                log.info("[支付宝小程序] 用户:{} 创建订单失败，返回值：{}", accountId, GSON.toJson(response));
            }
        } catch (Exception e) {
            log.error("[支付宝小程序] 用户:{} 创建订单异常", accountId, e);
        }
        return null;
    }

    @Override
    public LinkedHashMap<String, String> callOrder(HttpServletRequest request) {
        Factory.setOptions(getOptions());
        log.info("套餐回调参数" + request);
        try {
            BufferedReader br = request.getReader();
            String str;
            StringBuilder sb = new StringBuilder();
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            //回调的待验签字符串
            String params = URLUtil.decode(sb.toString(), "utf-8");
            //对待签名字符串数据通过&进行拆分
            String[] temp = params.split("&");
            LinkedHashMap<String, String> map = new LinkedHashMap<>();
            //把拆分数据放在map集合内
            for (int i = 0; i < temp.length; i++) {
                //通过"="号分割成2个数据
                String[] arr = temp[i].split("=", 2);
                //再开辟一个数组用来接收分割后的数据
                String[] tempAagin = new String[arr.length];
                for (int j = 0; j < arr.length; j++) {
                    tempAagin[j] = arr[j];
                }
                map.put(tempAagin[0], tempAagin[1]);
            }
            log.info("支付回调构造参数: {}", map);
            String outTradeNo = map.get("out_trade_no");
            String tradeStatus = map.get("trade_status");
            log.info("支付宝小程序支付-回调信息-订单：{}，交易状态：{}", outTradeNo, tradeStatus);
            boolean verifyNotify = AlipaySignature.rsaCheckV1(map, PUBLIC_KEY, "utf-8", "RSA2");
            log.info("支付宝小程序支付-验签结果: {}", verifyNotify);

            if (Boolean.TRUE.equals(verifyNotify)) {
                return map;
            } else {
                log.info("支付宝小程序支付-验签失败，回调参数: {}", params);
            }
        } catch (Exception e) {
            log.error("支付宝小程序支付-验签异常，原因：" + e.getMessage(), e);
        }

        return null;
    }

    @Override
    public LinkedHashMap<String, String> callOrderForMembershipCard(HttpServletRequest request) {
        Factory.setOptions(getOptions());
        log.info("年卡支付回调参数" + request);
        try {
            BufferedReader br = request.getReader();
            String str;
            StringBuilder sb = new StringBuilder();
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            //回调的待验签字符串
            String params = URLUtil.decode(sb.toString(), "utf-8");
            //对待签名字符串数据通过&进行拆分
            String[] temp = params.split("&");
            LinkedHashMap<String, String> map = new LinkedHashMap<>();
            //把拆分数据放在map集合内
            for (int i = 0; i < temp.length; i++) {
                //通过"="号分割成2个数据
                String[] arr = temp[i].split("=", 2);
                //再开辟一个数组用来接收分割后的数据
                String[] tempAagin = new String[arr.length];
                for (int j = 0; j < arr.length; j++) {
                    tempAagin[j] = arr[j];
                }
                map.put(tempAagin[0], tempAagin[1]);
            }
            log.info("支付回调构造参数: {}", map);
            String outTradeNo = map.get("out_trade_no");
            String tradeStatus = map.get("trade_status");
            log.info("支付宝小程序支付-回调信息-订单：{}，交易状态：{}", outTradeNo, tradeStatus);
            boolean verifyNotify = AlipaySignature.rsaCheckV1(map, PUBLIC_KEY, "utf-8", "RSA2");
            log.info("支付宝小程序支付-验签结果: {}", verifyNotify);

            if (Boolean.TRUE.equals(verifyNotify)) {
                return map;
            } else {
                log.info("支付宝小程序支付-验签失败，回调参数: {}", params);
            }
        } catch (Exception e) {
            log.error("支付宝小程序支付-验签异常，原因：" + e.getMessage(), e);
        }

        return null;
    }

    @Override
    public String tradeRefund(String tradeNo, String refundAmount, String refundReason, String refundNo) {
        Factory.setOptions(getOptions());
        Map<String, String> textParams = new HashMap<>();
        Map<String, Object> bizParams = new HashMap<>();
        bizParams.put("refund_amount", refundAmount);
        bizParams.put("out_trade_no", tradeNo);
        bizParams.put("refund_reason", refundReason);
        bizParams.put("out_request_no", refundNo);
        try {
            AlipayOpenApiGenericResponse response = Factory.Util.Generic().execute("alipay.trade.refund", textParams, bizParams);
            if (ResponseChecker.success(response)) {
                log.info("[支付宝小程序] 订单：{} 退款金额变更成功，退款单号为：{}", tradeNo, refundNo);
                return response.getHttpBody();
            } else {
                log.info("[支付宝小程序] 订单：{} 退款金额变更失败，返回值：{}", tradeNo, GSON.toJson(response));
            }
        } catch (Exception e) {
            log.error("[支付宝小程序] 订单：{} 退款金额变更异常", tradeNo, e);
        }
        return null;
    }

    @Override
    public String queryRefund(String tradeNo, String refundNo) {
        Factory.setOptions(getOptions());
        Map<String, String> textParams = new HashMap<>();
        Map<String, Object> bizParams = new HashMap<>();
        bizParams.put("out_request_no", refundNo);
        bizParams.put("out_trade_no", tradeNo);
        try {
            AlipayOpenApiGenericResponse response = Factory.Util.Generic().execute("alipay.trade.fastpay.refund.query", textParams, bizParams);
            if (ResponseChecker.success(response)) {
                log.info("[支付宝小程序] 订单：{} 退款信息查询成功，退款单号为：{}", tradeNo, refundNo);
                return response.getHttpBody();
            } else {
                log.info("[支付宝小程序] 订单：{} 退款信息查询失败，返回值：{}", tradeNo, GSON.toJson(response));
            }
        } catch (Exception e) {
            log.error("[支付宝小程序] 订单：{} 退款信息查询异常", tradeNo, e);
        }
        return null;
    }

    public String transfer() throws AlipayApiException {
        String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCQe0rN1jWa4RigOlv+zn6BONOXmw1Tk5bV3NfkTTuqk3GcM8QDexL6A53AseiBTe02+Ue1MzXPGaKzaKBS3hTz7UY5cqwvtQGFLfXnTjMdDpcu66zj8iMGYLPgPYtB9ucEaAtyCJRzpCyhTV+W0zmPsTJVDu7efGBBHlAHQBptyUqX9OtMCTfoY+DC3Y8IdEkCM+aiRilZWvMplqe1/laZgLe4hZykfP9NOR8abdffJ8p1hOiY/ezMLqF3/ILgC2ESMDeWOKzO2Jfv/l2GUVrv/YheeqJYq5DnZxeDCQq7rtYZKv7hqWg5VLiogrepaK1mOumjjK6joDPuJoy8PdHJAgMBAAECggEAWTH0RUzH/RyXwlsk7hJ24Lm/Tunm+UC1LsRO99+CRVUPHzqJ+Qgi9/wBiLOMcT81gem1DjVWM8uEuTOPPnliABDseIzFphIdpSVxmOGbBoY6aToPmw2h9879XSNBdHDDv+GnpzeKxjWFY/NLXuZ5s67V/tLgPrQUDD91cnRtnHZkYH5pOjC8xI/ycUzfkNsRyEst1kZaUQEA2JTfmRwZQWH3p3ROqMBzHzXq2jXCMZo86iCDPtmqE30vM7LWI0KEWIt5TnOz10eLMTcYlqu8zsnyEssMHSoScpeVngsRD9gIplSmf+DPhLEMsHk+h6WBnE4M4VoPFdm6TkWZnK+4gQKBgQDt4id7IX57SoTlTo852m+2pgFN+Np61wX74XOBpmwlbO3b0eoWDQWAxT086mPzbbD0CoKeNSyjKZMMnIfE3hLHL86wcS50Wy/eijbbEiBBWF+8MAS/w/9JrhOBW1nBnfj/XJOWfXFx+f6ogEnL9vtR99/Fvr4zmU0QDZuNOhaOeQKBgQCbfCYMeWtg5JTZuK8i6QuVst7aOs3POc4ny+nSRGtbytocjSuJV/1bfgL+wUlSaTkkaDqAM7x6MM01jGhcTKsMerUwjGd3KAgZsHqM/Y60U0g4cEIfC0KBccRDcHofR6dsAQBWBQvbgtBx9NGrlqmPiDMBH0jjOk57cSF9UgtJ0QKBgGDWmsnmRa39FQKgK3AauzV4eLl8H7y4Aeiay8GwtP+7S00cNBYL8PyNzrMYm93B/rIqAShUbzpwtzsAEckTukM59AMh4A5f/Km0TEZ8J4NSbY6XYaeLK0acRbZ4MJ7AJ1gVIMO3h1IlugRwTRpqDb89j+vZDWbF9ngdggBI8FvJAoGBAIQZdjoi7pfjnJNd1W5TkQQedDf0vebRtdUZ6g47Evtp3OVlCxglKZwR83l9vk3GGEZWR12klv05eR+FqyS//pMbrdURdNZHrJom1ffzdMq/9xv8RDEb3+UaQyUI6rioqBWaxC5RG0HkYjRvS7P8zRKlJLBPZB2p7AP0mf9fNTgBAoGASUJiWp0isRayuT32EU/bL6+yCgj+Pm5kBtVicndsJYNMseHsLtv/QpRYNy0dSe6qFVwLcz1h6mlRf6enm8npPjbRFzH2XHWSWAbAiLkswZudooFegrfWDBEKZVjK1ECkfRdvEDn2C9HsuRFWILYYMfNy5xu1gPvupwzR5ivJzNI=";
        CertAlipayRequest alipayConfig = new CertAlipayRequest();
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setServerUrl("https://openapi-sandbox.dl.alipaydev.com/gateway.do");
        alipayConfig.setAppId("9021000127663508");
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");
        alipayConfig.setEncryptor("");
        alipayConfig.setFormat("json");
        // 如果不使用content的模式,那么这里需要自行设置文件的绝对路径
        alipayConfig.setCertPath("cert的绝对路径");
        alipayConfig.setAlipayPublicCertPath("AlipayPublicCertPath的绝对路径");
        alipayConfig.setRootCertPath("RootCertPath的绝对路径");
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
        model.setOutBizNo("201806300001");
        model.setTransAmount("23.00");
        model.setProductCode("TRANS_ACCOUNT_NO_PWD");
        Participant payeeInfo = new Participant();
        payeeInfo.setIdentity("testaccount@alipay.com");
        payeeInfo.setIdentityType("ALIPAY_OPEN_ID");
        BankcardExtInfo bankcardExtInfo = new BankcardExtInfo();
        bankcardExtInfo.setInstName("招商银行");
        bankcardExtInfo.setAccountType("1");
        payeeInfo.setBankcardExtInfo(bankcardExtInfo);
        model.setPayeeInfo(payeeInfo);
        request.setBizModel(model);
        AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request);
        System.out.println(response.getBody());
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        Factory.setOptions(getOptions());
        Map<String, String> textParams = new HashMap<>();
        Map<String, Object> bizParams1 = new HashMap<>();
        bizParams1.put("refund_amount", "0.01");
        bizParams1.put("out_trade_no", "4ac8733e82bf46bfb5998f1cde550601");
        bizParams1.put("refund_reason", "查询未成功");
        bizParams1.put("out_request_no", "test051406");

//        AlipayTradeRefundRequest
        AlipayOpenApiGenericResponse response1 = Factory.Util.Generic().execute("alipay.trade.refund", textParams, bizParams1);
        System.out.println(response1.getHttpBody());
        System.out.println(GSON.fromJson(response1.getHttpBody(), JsonObject.class).getAsJsonObject("alipay_trade_refund_response"));
        Map<String, Object> bizParams2 = new HashMap<>();
        bizParams2.put("out_request_no", "test051406");
        bizParams2.put("out_trade_no", "4ac8733e82bf46bfb5998f1cde550601");
        AlipayOpenApiGenericResponse response2 = Factory.Util.Generic().execute("alipay.trade.fastpay.refund.query", textParams, bizParams2);
        System.out.println(response2.getHttpBody());
    }
}
